#include "gdal.h"
#include "cpl_string.h"

extern GDALDatasetH createMeomroyDataset(int nBands, int nXSize, int nYSize);
extern void copyToMemory(GDALDatasetH memDS, GByte *bandData, int nthBands, int nXSize, int nYSize);
void saveAsPngFile(GDALDatasetH hDstDS, char *file_name);

int length(GByte * data) {
    int len = 0;
    for(; *data != '\0'; ++data) {
        ++len;
    }
    return len;
}

int main() {
    GDALDatasetH hDataset;
    CPLErr eErr = CE_None;
    GDALAllRegister();
FILE* fp = fopen("err.log", "a");
    hDataset = GDALOpen("01.jpg", GA_ReadOnly);
    if (hDataset == NULL) {
        printf("NULL\n");
    }
    else {
        printf("---> GDAL open OK <---\n");
    }

    GDALDriverH hDriver;

    hDriver = GDALGetDatasetDriver(hDataset);
    printf("Driver: %s/%s\n",
            GDALGetDriverShortName(hDriver),
            GDALGetDriverLongName(hDriver));

    printf("Size is %dX%dX%d\n",
            GDALGetRasterXSize(hDataset),
            GDALGetRasterYSize(hDataset),
            GDALGetRasterCount(hDataset));

    GDALRasterBandH hBand;
    int nBlockXSize, nBlockYSize;
    int bGotMin, bGotMax;
    double adfMinMax[2];

    hBand = GDALGetRasterBand(hDataset, 1);
    GDALGetBlockSize(hBand, &nBlockXSize, &nBlockYSize);
    printf("Block=%dx%d Type=%s, ColorInterp=%s\n",
            nBlockXSize, nBlockYSize,
            GDALGetDataTypeName(GDALGetRasterDataType(hBand)),
            GDALGetColorInterpretationName(
                GDALGetRasterColorInterpretation(hBand)));

    adfMinMax[0] = GDALGetRasterMinimum(hBand, &bGotMin);
    adfMinMax[1] = GDALGetRasterMaximum(hBand, &bGotMax);

    printf("==-==>\n");
    GDALGetRasterCategoryNames(hBand);
//    if ( ! (bGotMin && bGotMax))
//        GDALComputeRasterMinMax(hBand, TRUE, adfMinMax);
    printf("--=-->\n");

    printf("Min=%.3f, Max=%.3f\n", adfMinMax[0], adfMinMax[1]);
 
    GByte *pafScanline;
    int nXSize = GDALGetRasterBandXSize(hBand);
    int nYSize = GDALGetRasterBandYSize(hBand);

    pafScanline = (GByte *) CPLMalloc(sizeof(GByte) * nXSize * nYSize);
    printf("data size: %d\n", length(pafScanline));
    printf("---->\n");
CPLPushErrorHandler( CPLQuietErrorHandler );
    GDALRasterIO(hBand, GF_Read, 0, 0, nXSize, nYSize, 
                pafScanline, nXSize, nYSize,
                GDT_Byte, 
                0, 0);
CPLPopErrorHandler();
       if( eErr == CE_None )
        {
            printf( " none\n");
        }
        else {
            printf("something wrong");
        }
    printf("---->\n");

    printf("X-size: %d, y-size: %d, sizeof GByte: %d\n", nXSize, nYSize, sizeof(GByte));
    printf("data size: %d\n", length(pafScanline));
   
    GDALDatasetH hDstDS = createMeomroyDataset(1, nXSize, nYSize);
    copyToMemory(hDstDS, pafScanline, 1, nXSize, nYSize);

    //saveAsPngFile(hDstDS); 
    //VSIInstallMemFileHandler();
    GDALDriverH tmpDriver = GDALGetDriverByName("PNG");
    GDALDatasetH hOutDS = GDALCreateCopy(tmpDriver, "/vsimem/out.png", 
                            hDstDS, TRUE,
                            NULL, NULL, NULL);
    vsi_l_offset outDataLength;
    GByte * binData = NULL;
    
    GDALClose(hOutDS);        

    GDALClose(hDstDS);
    GDALClose(hDataset);
    
    binData =VSIGetMemFileBuffer("/vsimem/out.png", &outDataLength, TRUE);
//    int len = length(binData);
    if (binData == NULL)
        printf("hell\n");
    printf("binary size: %d\n\n", outDataLength);
    
GDALDumpOpenDatasets(fp);
    fclose(fp);
}

